package com.novoda.runbuddy.view;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;

import android.app.Activity;
import android.text.Layout.Alignment;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.ViewSwitcher.ViewFactory;

import com.novoda.runbuddy.R;
import com.novoda.runbuddy.controller.CalendarControllerImpl;
import com.novoda.runbuddy.model.PastRunsCalendar;

public class CalendarView implements ViewFactory {

	private Activity						activity;

	private LinkedHashMap<Integer, Button>	tableOfCalendarDatesView;
	private LinkedHashMap<Integer, Integer>	tableOfCalendarDatesModel;
	private ArrayList<Integer>				joggingDaysInThisMonth;
	private CalendarControllerImpl			pastJogsController;
	private TextView						currentMonth;
	private Integer							indexOfTodayCell;

	private Button							dayContext;
	private Button							monthContext;
	private Button							yearContext;
	private Button							backwardPeriod;
	private Button							forwardPeriod;

	public static final int					NOTIFICATION_ID			= 0x1337;
	public static final int					IMAGESUBACTIVITY_ID		= 0x7331;

	public static final String				DRAWABLE_RESID_MARKER	= "DRAWABLE_RESID_MARKER";
	public static final String				CAPTION_TO_SHOW_MARKER	= "CAPTION_TO_SHOW_MARKER";
	protected static final int				DAY_CONTEXT_SELECTED	= 00;
	private static final int				MONTH_CONTEXT_SELECTED	= 11;
	private static final int				YEAR_CONTEXT_SELECTED	= 22;

	public CalendarView(Activity activity, CalendarControllerImpl pastJogsViewController, TextView currentMonth, Button dayContext,
			Button monthContext, Button yearContext, Button backwardPeriod, Button forwardPeriod) {

		this.activity = activity;
		this.pastJogsController = pastJogsViewController;

		this.currentMonth = currentMonth;

		this.dayContext = dayContext;
		this.monthContext = monthContext;
		this.yearContext = yearContext;
		this.backwardPeriod = backwardPeriod;
		this.forwardPeriod = forwardPeriod;

		setSwitchDayListener(switchDayListener);
		setSwitchMonthListener(switchMonthListener);
		setSwitchYearListener(switchYearListener);

		setForwardPeriod(dayForwardListener);
		setBackwardPeriod(dayBackListener);
	}

	public void updateCalendarView(PastRunsCalendar pastJogsCalendar) {
		tableOfCalendarDatesModel = pastJogsCalendar.getDaysInMonthTable();
		currentMonth.setText(pastJogsCalendar.getCurrentShowingMonth());
		joggingDaysInThisMonth = new ArrayList<Integer>();

		for (int currentRow = 0; currentRow <= pastJogsCalendar.NO_OF_ROWS; currentRow++) {

			for (int currentCol = 0; currentCol <= pastJogsCalendar.NO_OF_COLS; currentCol++) {
				updateCalendarViewCellWithCalendarModelCell(currentCol, currentRow);
			}
		}
	}

	private void updateCalendarViewCellWithCalendarModelCell(int currentCol, int currentRow) {
		String tableIndex = new String(String.valueOf(currentRow) + String.valueOf(currentCol));

		Button cellInView = (Button) tableOfCalendarDatesView.get(Integer.valueOf(tableIndex));
		Integer cellInModel = tableOfCalendarDatesModel.get(Integer.valueOf(tableIndex));

		cellInView.setText(cellInModel.toString());
		Integer indexOfInsertion = Integer.valueOf(tableIndex);
		tableOfCalendarDatesView.put(indexOfInsertion, (Button) cellInView);

	}

	private void setPeriodChangeContext(int dayContextSelected) {
		switch (dayContextSelected) {
			case DAY_CONTEXT_SELECTED:
				setForwardPeriod(dayForwardListener);
				setBackwardPeriod(dayBackListener);
				break;
			case MONTH_CONTEXT_SELECTED:
				setForwardPeriod(monthForwardListener);
				setBackwardPeriod(monthBackListener);
				break;
			case YEAR_CONTEXT_SELECTED:
				setForwardPeriod(yearForwardListener);
				setBackwardPeriod(yearBackListener);
				break;
		}
	}

	private void setForwardPeriod(OnClickListener listener) {
		this.forwardPeriod.setOnClickListener(listener);
	}

	private void setBackwardPeriod(OnClickListener listener) {
		this.backwardPeriod.setOnClickListener(listener);
	}

	public void removeAllCellHighlights() {

		for (Iterator<Entry<Integer, Button>> iter = tableOfCalendarDatesView.entrySet().iterator(); iter.hasNext();) {
			Entry<Integer, Button> cell = iter.next();
			cell.getValue().setBackgroundDrawable((activity.getResources().getDrawable(R.color.calcell_background)));
			tableOfCalendarDatesView.put(cell.getKey(), cell.getValue());
		}

	}

	public void setCellsInCalendarTable(LinkedHashMap<Integer, Button> tableCells) {
		this.tableOfCalendarDatesView = tableCells;
	}

	public void addDayClickListeners(LinkedHashMap<Integer, Button> tableCells) {

		for (Iterator<Entry<Integer, Button>> iter = tableCells.entrySet().iterator(); iter.hasNext();) {
			Entry<Integer, Button> entry = iter.next();
			final Button cell = (Button) entry.getValue();
			final Integer position = (Integer) entry.getKey();

			cell.setOnClickListener(clickADay);
			tableOfCalendarDatesView.put(position, cell);
		}

	}

	public void setCurrentlySelectedDay(Integer index) {
		Button cellInView = (Button) tableOfCalendarDatesView.get(index);
		cellInView.setBackgroundDrawable(activity.getResources().getDrawable(R.color.solid_yellow));
		indexOfTodayCell = index;
	}

	public void removeHighlightOnTodayCellInTable() {
		Button cellInView = (Button) tableOfCalendarDatesView.get(indexOfTodayCell);
		cellInView.setBackgroundDrawable(activity.getResources().getDrawable(R.color.calcell_background));
	}

	public void setAHighightedDayOfRunning(Integer index) {
		Button cellInView = (Button) tableOfCalendarDatesView.get(index);
		cellInView.setBackgroundDrawable(activity.getResources().getDrawable(R.color.solid_red));
		joggingDaysInThisMonth.add(index);
	}

	public void setSwitchDayListener(OnClickListener listener) {
		dayContext.setOnClickListener(listener);
	}

	public void setSwitchMonthListener(OnClickListener listener) {
		monthContext.setOnClickListener(listener);
	}

	public void setSwitchYearListener(OnClickListener listener) {
		yearContext.setOnClickListener(listener);
	}

	private OnClickListener	yearBackListener		= new OnClickListener()
													{
														public void onClick(View v) {
															pastJogsController.ammendCurrentlyShowingDate(Calendar.YEAR, -1);
														}
													};
	private OnClickListener	monthBackListener		= new OnClickListener()
													{
														public void onClick(View v) {
															pastJogsController.ammendCurrentlyShowingDate(Calendar.MONTH, -1);
														}
													};
	private OnClickListener	dayBackListener			= new OnClickListener()
													{
														public void onClick(View v) {
															pastJogsController
																	.ammendCurrentlyShowingDate(Calendar.DAY_OF_MONTH, -1);
														}
													};
	private OnClickListener	dayForwardListener		= new OnClickListener()
													{
														public void onClick(View v) {
															pastJogsController.ammendCurrentlyShowingDate(Calendar.DAY_OF_MONTH, 1);
														}
													};
	private OnClickListener	monthForwardListener	= new OnClickListener()
													{
														public void onClick(View v) {
															pastJogsController.ammendCurrentlyShowingDate(Calendar.MONTH, 1);
														}
													};
	private OnClickListener	yearForwardListener		= new OnClickListener()
													{
														public void onClick(View v) {
															pastJogsController.ammendCurrentlyShowingDate(Calendar.YEAR, 1);
														}
													};

	private OnClickListener	switchDayListener		= new OnClickListener()
													{
														public void onClick(View v) {
															setPeriodChangeContext(DAY_CONTEXT_SELECTED);
														}
													};
	private OnClickListener	switchMonthListener		= new OnClickListener()
													{
														public void onClick(View v) {
															setPeriodChangeContext(MONTH_CONTEXT_SELECTED);
														}
													};
	private OnClickListener	switchYearListener		= new OnClickListener()
													{
														public void onClick(View v) {
															setPeriodChangeContext(YEAR_CONTEXT_SELECTED);
														}
													};
	public OnClickListener	clickADay				= new OnClickListener()
													{
														public void onClick(View aView) {
															Button clickedButton = (Button) aView;
															String buttonCaption = clickedButton.getText().toString();
															pastJogsController.loadDayDetails(buttonCaption);
														}
													};

	public View makeView() {
		TextView textView = new TextView(activity);
		textView.setGravity(Gravity.CENTER);
		textView.setTextSize(50);
		return textView;
	}

}
